﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using Comm.PublicClass;
using WsProtocol.IEC62056;
using WsProtocol.IEC62056.DLL;
using WsProtocol.IEC62056.DataTypeClass;
using System.Text;
using WsProtocol.PublicClass;

namespace WsProtocol.IEC62056MDL
{
    public class PubFunc62056
    {
        public delegate void EventAfterSelectObAttr(ProObAttr obattr);  //选中对象之后执行的操作委托

        //设置抄读界面刷新数据委托
        public delegate void ReLoadObj(List<ProObject> Objlst);


        public static Hashtable SpecialFuncLst = new Hashtable();  //特殊处理函数名对照表
        public static ReLoadObj doReloadObj = null;  //设置抄读界面刷新数据操作

        private static List<string> PreConnClientAddrLst = new List<string>();  //预连接角色

        /// <summary>
        /// 初始化协议中间层
        /// </summary>
        public static void InitIEC62056MDL(string LanType)
        {
            //PtlConsts.easyDb = aDb;
            PtlConsts.LanType = LanType == "cn" ? "" : LanType;//数据库中中文字段未带cn
            InitSpecialFunc();
            InitPreConnClientAddrLst();
        }

        //public static void BeginTrans()
        //{
        //    if (PtlConsts.easyDb != null)
        //        PtlConsts.easyDb.BeginTrans();
        //}

        //public static void RollbackTrans()
        //{
        //    if (PtlConsts.easyDb != null)
        //        PtlConsts.easyDb.RollbackTrans();
        //}


        //public static void CommitTrans()
        //{
        //    if (PtlConsts.easyDb != null)
        //        PtlConsts.easyDb.CommitTrans();
        //}

        /// <summary>
        /// 初始化可用预连接角色
        /// </summary>
        private static void InitPreConnClientAddrLst()
        {
            PreConnClientAddrLst.Clear();
            PreConnClientAddrLst.Add("102");  //IDIS预连接角色
        }

        /// <summary>
        /// 判断是否是预连接角色
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static bool CheckPreConnClient(string client)
        {
            return PreConnClientAddrLst.IndexOf(client) >= 0;
        }

        public static void FuncPreSend(ProObAttr proObAttr, string opflag)
        {

            if (proObAttr.DataTypeDIY == enumData.ModuleParas.ToString()) //hxh 2019-7-23 模块参数处理
            {
                proObAttr.ParLst.Clear();
                if (opflag.Contains("读取"))
                {
                    ProObAttr EntryAttr = new ProObAttr(new object[] { "记录选择", "", "元素", 1, enumData.structure.ToString(), "", "", "" });
                    EntryAttr.inputValue = "2"; //选择性访问方法2
                    string ModulID = MyConvert.HexToDec(proObAttr.EleLst[0].inputValue);
                    ProObAttr ele = new ProObAttr(new object[] { "起始值", "", "元素", 1, enumData.double_long_unsigned.ToString(), "", "", "" });
                    ele.inputValue = ModulID;
                    EntryAttr.EleLst.Add(ele);

                    ele = new ProObAttr(new object[] { "结束值", "", "元素", 1, enumData.double_long_unsigned.ToString(), "", "", "" });
                    ele.inputValue = ModulID;
                    EntryAttr.EleLst.Add(ele);

                    ele = new ProObAttr(new object[] { "列索引起始值", "", "元素", 1, enumData.long_unsigned.ToString(), "", "", "" });
                    ele.inputValue = "1";
                    EntryAttr.EleLst.Add(ele);

                    ele = new ProObAttr(new object[] { "列索引结束值", "", "元素", 1, enumData.long_unsigned.ToString(), "", "", "" });
                    ele.inputValue = "0";
                    EntryAttr.EleLst.Add(ele);

                    EntryAttr.EleNodetype = eleNodeType.AppendPar;
                    proObAttr.ParLst.Add(EntryAttr);

                    for (int i = 0; i < proObAttr.EleLst.Count; i++)
                        proObAttr.ParLst.Add(proObAttr.EleLst[i]);
              
                }
            }
            else
                return;
        }
        /// <summary>
        /// ProObAttr的值赋给CosemObject;   
        /// </summary>
        /// <param name="attrinfo"></param>
        /// <param name="oiobj"></param>
        /// 
        private static void AttrToOIObj(ProObAttr attrinfo, CosemObject oiobj)
        {
            //Tag
            oiobj.Tag = attrinfo; //hxh  赋attrinfo时其ID及PID在copy时赋为了空, 界面的抄读数据保存成方案时会报错

            //OI
            oiobj.OBIS = attrinfo.OBIS;

            //对象名称
            oiobj.AmName = attrinfo.ProName;

            //所属类
            if (attrinfo.proObject != null)
                oiobj.classid = attrinfo.proObject.proClass.ClassID;

            //属性索引
            oiobj.AttrSeq = attrinfo.Seq.ToString();

            //hxh 2018-7-6
            //AddElement(attrinfo, oiobj.DataNode);           
            AddDataOrParEleNode(attrinfo, oiobj); //hxh 给对象赋数据节点或附加参数节点
        }

        //hxh 根据属性的元素节点类型给对象赋数据节点或附加参数节点
        private static void AddDataOrParEleNode(ProObAttr attr, CosemObject obj)
        {
            AttrToElement(attr, obj.DataNode);  //属性本身肯定为数据节点， 下面的元素节点或为数据节点或为附加参数节点
            for (int i = 0; i < attr.EleLst.Count; i++)
            {
                ProObAttr attrinfo = attr.EleLst[i];//hxh 2018-7-11 属性下的元素应该都是有用，而不需用checked来判断
                //if (attrinfo.checkState != true)
                //    continue;
                ElementData EleNode = new ElementData();
                AttrToElement(attrinfo, EleNode);
                if (attrinfo.EleNodetype == eleNodeType.AppendPar)
                {
                    obj.AddAppendOb(EleNode);  //如果为附加数节点，则赋给对象的附加参数节点
                }
                else
                {
                    obj.DataNode.AddNode(EleNode);
                }

                AddElement(attrinfo, EleNode);//增加下级元素节点
            }

        }


        //添加元素的子元素
        public static void AddElement(ProObAttr attr, ElementData pelement)
        {
            AttrToElement(attr, pelement);
            if (attr.ParLst != null && attr.ParLst.Count > 0) //hxh 2019-11-8 某些情况元素节点也会存在ParLst有值
            {
                attr.EleLst.Clear();
                for (int p = 0; p < attr.ParLst.Count; p++)
                    attr.EleLst.Add(attr.ParLst[p].Copy());
            }
            if (attr.EleLst != null && attr.EleLst.Count > 0)
            {
                for (int i = 0; i < attr.EleLst.Count; i++)
                {
                    ProObAttr attrinfo = attr.EleLst[i];
                    //这里开始添加属性元素
                    ElementData newele = new ElementData();
                    if (attrinfo.ParLst != null && attrinfo.ParLst.Count > 0) //某些情况元素节点也会存在ParLst有值
                    {
                        attrinfo.EleLst.Clear();
                        for (int p = 0; p < attrinfo.ParLst.Count; p++)
                            attrinfo.EleLst.Add(attrinfo.ParLst[p].Copy());
                    }
                    AttrToElement(attrinfo, newele);
                    pelement.AddNode(newele);

                    AddElement(attrinfo, newele);//递归一下  万一还有下级元素呢

                }
            }
        }


        private static void AttrToElement(ProObAttr eleattr, ElementData newele)
        {
            //对应的ProObAttr对象
            newele.Tag = eleattr;

            newele.CAD = eleattr.CAD; //保存某些需要的CAD
            //数据项名
            newele.ValueName = eleattr.ProName;
            if(string.IsNullOrEmpty(eleattr.ProName))
              newele.ValueName =  eleattr.BaseProName;
            //是否有效
            newele.visible = eleattr.IsVisible;

            //实际设置值
            newele.SetValue = eleattr.InputToFrame();

            //界面传入值
            newele.InputValue = eleattr.inputValue;

            //数据类型
            newele.DataType = eleattr.DataType;

            //数据长度
            newele.DataLen = eleattr.DataLen;
            if (string.IsNullOrEmpty(newele.DataLen))  //shaunwang 2019-9-29
                newele.DataLen = "0";

            //换算
            newele.Scaler = eleattr.Scaler;

            //单位
            newele.Units = eleattr.Units;

            //显示格式
            newele.ShowFormat = eleattr.ShowFormat;

            //分解描述 
            newele.Display = eleattr.Display;

            newele.tmpOption = eleattr.tmpOption;

            newele.DataTypeDIY = eleattr.DataTypeDIY; //自定义数据类型

        }


        /// <summary>
        /// 增加格式
        /// </summary>
        /// <param name="ptl62056"></param>
        /// <param name="attrinfo"></param>
        /// <param name="bpropnode">是否需要有属性那层</param>
        /// <param name="forAna">是否是为了生成解析类</param>
        /// <param name="enctype"></param>
        public static void AddFormat(Analysis62056.TProtocol62056 ptl62056, ProObAttr attrinfo, bool forAna) //增加格式
        {
            CosemObject oiobj = CreateOIObjByObAttr(attrinfo); //新建OI对象
            ptl62056.ptlformat.Apdu.AddObAttribute(oiobj);


        }

        /// <summary>
        /// 根据ProObAttr生成CosemObject
        /// </summary>
        /// <param name="attrinfo"></param>
        /// <param name="bpropnode"></param>
        /// <param name="enctype"></param>
        /// <returns></returns>
        public static CosemObject CreateOIObjByObAttr(ProObAttr attrinfo)
        {
            ProObject proObj = attrinfo.proObject;

            CosemObject oiobj = new CosemObject(); //新建OI对象

            AttrToOIObj(attrinfo, oiobj);

            return oiobj;
        }


        /// <summary>
        /// 旧格式转为新格式
        /// </summary>
        /// <returns></returns>
        public static string TransOldDatatype(string sdatatype)
        {
            string rs = sdatatype;
            switch (sdatatype)
            {
                case "bstring":
                    rs = "bit_string";
                    break;

                case "octString":
                    rs = "octet_string";
                    break;
                case "visiblestring":
                    rs = "visible_string";
                    break;
                case "Bool":
                    rs = "boolean";
                    break;
                case "doublelong":
                    rs = "double_long";
                    break;
                case "doublelongunsigned":
                    rs = "double_long_unsigned";
                    break;
                case "BCD":
                    rs = "bcd";
                    break;
                case "ilong":
                    rs = "Long";
                    break;
                case "longunsigned":
                    rs = "long_unsigned";
                    break;
                case "datetime":
                    rs = "date_time";
                    break;
                case "UTF8_string":
                    rs = "utf8_string";
                    break;
                case "Comarray":
                    rs = "compact_array";
                    break;
            }
            return rs;
        }


        /// <summary>
        /// 根据数据类型获取对应的显示格式
        /// </summary>
        /// <param name="sformtype"></param>
        /// <returns></returns>
        public static string GetFormatByFormType(string sdatatype)
        {
            string showformat = "";
            if (sdatatype == "")
                return showformat;
            enumData datatype = (enumData)Enum.Parse(typeof(enumData), sdatatype);   //数据类型
            switch (datatype)
            {
                case enumData.date:
                    showformat = "yyyy-MM-dd ww";
                    break;
                case enumData.date_time:
                    showformat = "yyyy-MM-dd ww HH:mm:ss hs nnnn:st";
                    break;
                case enumData.time:
                    showformat = "HH:mm:ss hs";
                    break;

            }

            return showformat;
        }

        /// <summary>
        /// 根据数据类型获取对应的显示窗口
        /// </summary>
        /// <param name="sformtype"></param>
        /// <returns></returns>
        public static string GetParformByType(string sdatatype)
        {
            int Parform = 0;
            if (sdatatype == "")
                return Parform.ToString();
            enumData datatype = (enumData)Enum.Parse(typeof(enumData), sdatatype);   //数据类型
            switch (datatype)
            {
                case enumData.date:
                    Parform = (int)TFormType.日期带周次;
                    break;
                case enumData.date_time:
                    Parform = (int)TFormType.日期时间带周次毫秒;
                    break;
                case enumData.array:
                    Parform = (int)TFormType.数组类型对象参数;
                    break;
                case enumData.unsigned:
                case enumData.double_long_unsigned:
                case enumData.long_unsigned:
                case enumData.integer:
                case enumData.Long:
                case enumData.long64:
                case enumData.double_long:
                    Parform = (int)TFormType.数字框;
                    break;
                case enumData.Enum:
                    Parform = (int)TFormType.下拉框;
                    break;
            }

            return Parform.ToString();
        }


        /// <summary>
        /// 获取操作名称
        /// </summary>
        /// <param name="rwflag"></param>
        /// <returns></returns>
        public static string GetOperationName(ClientApduSel rwflag)
        {
            string showOperate = "";
            switch (rwflag)
            {
                case ClientApduSel.GETRequest:
                    showOperate = "读取";
                    break;
                case ClientApduSel.SETRequest:
                    showOperate = "设置";
                    break;
                case ClientApduSel.ActionRequest:
                    showOperate = "操作";
                    break;
                case ClientApduSel.EventRequest:
                    showOperate = "事件请求";
                    break;
            }
            return showOperate;
        }

        /// <summary>
        /// 生成62056指令
        /// </summary>
        /// <param name="funC">控制码中功能码部分</param>
        /// <param name="Meter62056">表对象</param>
        /// <param name="AttrLst">对象列表</param>
        /// <param name="rwflag">应用层提供的数据交换服务</param>
        /// <param name="rwtype">读写选择类型</param>
        /// <param name="enctype">加密方式</param>
        /// <param name="errorinfo">错误信息</param>
        /// <returns></returns>
        public static string CreateOrder(Analysis62056.TProtocol62056 orderptl, EnuFrameType funC, TMeter62056 ameter, List<ProObAttr> AttrLst, ClientApduSel rwflag, string rwtype, ref string errorinfo)
        {
            return CreateOrderOrPayload(orderptl, funC, ameter, AttrLst, rwflag, rwtype, 0, ref errorinfo);
        }


        /// <summary>
        /// 生成62056指令
        /// </summary>
        /// <param name="funC">控制码中功能码部分</param>
        /// <param name="Meter62056">表对象</param>
        /// <param name="AttrLst">对象列表</param>
        /// <param name="rwflag">应用层提供的数据交换服务</param>
        /// <param name="rwtype">读写选择类型</param>
        /// <param name="enctype">加密方式</param>
        /// <param name="errorinfo">错误信息</param>
        /// <param name="orderorpayload">0:生成完整指令  1:只要纯数据部分</param>
        /// <returns></returns>
        public static string CreateOrderOrPayload(Analysis62056.TProtocol62056 orderptl, EnuFrameType funC, TMeter62056 ameter, List<ProObAttr> AttrLst, ClientApduSel rwflag, string rwtype, int orderorpayload, ref string errorinfo)
        {
            string orderstr = string.Empty;

            orderptl.ptlformat.C.C_FrameType = funC; //控制码
            //orderptl.ptlformat.C.RRR = ameter.RecCount;  //接收计数器
            //orderptl.ptlformat.C.SSS = ameter.NewSendCount;  //发送计数器

            orderptl.RRR = ameter.RecCount;  //接收计数器
            orderptl.SSS = ameter.SendCount;  //发送计数器 hxh

            orderptl.ptlformat.Addr.CAddr = int.Parse(ameter.MTRole.RoleClientAddr);
            orderptl.ptlformat.Addr.SAddr_Lower = ameter.MeterCommAddr; //地址
            orderptl.ptlformat.Addr.SAddr_LEN = ameter.AddrLen;
            orderptl.ptlformat.Apdu.rwflag = rwflag; //读写标志
            //orderptl.ptlformat.Apdu.timetag = timetag;//时间标签
            orderptl.ptlformat.Apdu.rwtype = rwtype; //读写选择类型
            int APDUsize = PtlConsts.defApduSize;
            try
            {
                if (ameter.APDUSize != "0")
                    APDUsize = Convert.ToInt32(ameter.APDUSize);
            }
            catch
            { }
            orderptl.ptlformat.Apdu.ApduSize = APDUsize; //hxh 2018-5-16           
            orderptl.ptlformat.Apdu.encryption = ameter.EncParams;
            orderptl.ptlformat.Apdu.encryption.EncryptData = orderptl.ptlformat.Apdu.encryption.PlaintData = string.Empty;
            if (!string.IsNullOrEmpty(ameter.udpCAddr))  //47协议 udp模式
            {
                orderptl.ptlformat.udpCAddr = ameter.udpCAddr;
                orderptl.ptlformat.udpSAddr = ameter.udpSAddr;
            }

            try
            {
                string ordername = GetOperationName(rwflag);
                if (!string.IsNullOrEmpty(ordername))
                    ordername += "->";
                string parameterstr = string.Empty;
                //传入参数
                for (int i = 0; i < AttrLst.Count; i++)
                {
                    ProObAttr formatAttr = AttrLst[i].Copy();

                    string aname = AttrLst[i].ProName.Replace("\r", "").Replace("\n", "");
                    if (AttrLst[i].proObject != null && !string.IsNullOrEmpty(AttrLst[i].proObject.ProName))
                        aname = AttrLst[i].proObject.ProName.Replace("\r", "").Replace("\n", "")
                              + "->"
                              + aname;
                    ordername += aname;
                    if (i < AttrLst.Count - 1)
                        ordername += ",";

                    //解析后的特殊处理函数
                    if (!string.IsNullOrEmpty(formatAttr.AnaFunc))
                        orderptl.ptlinfo.AnaFunc += formatAttr.AnaFunc
                                                  + ",";

                    if (formatAttr.ParLst != null && formatAttr.ParLst.Count > 0)
                    {
                        formatAttr.EleLst.Clear();
                        for (int p = 0; p < formatAttr.ParLst.Count; p++)
                            formatAttr.EleLst.Add(formatAttr.ParLst[p].Copy());
                    }
                    else
                        PrepareObAttr(formatAttr, rwflag, 1);

                    AddFormat(orderptl, formatAttr, false);   //添加参数
                }


                orderptl.ptlinfo.DataName = ordername;
                switch (orderorpayload)
                {
                    case 0:  //生成完整指令
                        orderstr = orderptl.CreateOrder(rwtype, APDUsize, ref errorinfo);
                        break;
                    case 1:  //只要纯数据
                        orderstr = orderptl.ptlformat.Apdu.GetDataFormatValue(ref errorinfo);
                        break;
                    case 2: //生成完整的明文APDU数据
                        orderptl.ptlformat.Apdu.PIID = "81";
                        orderptl.ptlformat.Apdu.ApduSize = 2048; //尽量不分帧处理
                        orderstr = orderptl.ptlformat.Apdu.RequestApdu(ref errorinfo);
                        break;
                }
                
            }
            catch (Exception e)
            {
                errorinfo = e.Message;
            }


            return orderstr;  //返回生成的指令
        }


        /// <summary>
        /// 生成任意指令
        /// </summary>
        /// <param name="funC">控制码中功能码部分</param>
        /// <param name="Meter62056">表对象</param>
        /// <param name="rwflag">应用层提供的数据交换服务</param>
        /// <param name="rwtype">读写选择类型</param>
        /// <param name="pardata">链路用户数据</param>
        /// <param name="errorinfo">错误信息</param>
        /// <returns></returns>
        public static string CreateRandom(int funC, TMeter62056 Meter62056, string pardata, ref string errorinfo)
        {
            string orderstr = string.Empty;

            Analysis62056.TProtocol62056 orderptl = new Analysis62056.TProtocol62056();  //用于生成指令
            orderptl.ptlformat.C.C_FrameType = (EnuFrameType)funC;
            orderptl.ptlformat.C.RRR = Meter62056.RecCount;
            orderptl.ptlformat.C.SSS = Meter62056.SendCount;
            orderptl.ptlformat.Addr.CAddr = int.Parse(Meter62056.MTRole.RoleClientAddr);
            orderptl.ptlformat.Addr.SAddr_Lower = Meter62056.MeterCommAddr;
            orderptl.ptlformat.Addr.SAddr_LEN = Meter62056.AddrLen;
            // orderptl.ptlformat.Apdu.encryption = Meter62056.EncParams;

            if (!string.IsNullOrEmpty(Meter62056.udpCAddr))  //47协议 udp模式
            {
                orderptl.ptlformat.udpCAddr = Meter62056.udpCAddr;
                orderptl.ptlformat.udpSAddr = Meter62056.udpSAddr;
            }

            try
            {
                int APDUsize = 0;
                try
                {
                    APDUsize = Convert.ToInt16(Meter62056.APDUSize);
                }
                catch
                { }

                orderstr = orderptl.CreateRandom("", pardata, APDUsize, ref errorinfo);
            }
            catch (Exception e)
            {
                errorinfo = e.Message;
            }

            return orderstr;  //返回生成的指令
        }

        /// <summary>
        /// 获取校验
        /// </summary>
        /// <param name="datastr"></param>
        /// <returns></returns>
        public static string GetCS(string datastr)
        {
            Analysis62056.TProtocol62056 orderptl = new Analysis62056.TProtocol62056();  //用于生成指令
            return orderptl.CalcCS(datastr);
        }


        /// <summary>
        /// 获取解析用的协议格式类  hxh 2017-5-10增加一参数 RorW,一类参数的读写应用数据解密需调不同接口,得以此区分
        /// </summary>
        /// <param name="AttrLst"></param>
        /// <returns></returns>
        public static Analysis62056.TProtocol62056 CreateAnaPtl(TMeter62056 ameter, List<ProObAttr> AttrLst, ClientApduSel rwflag, string rwtype, ref string errorinfo)
        {
            Analysis62056.TProtocol62056 anaptl = new Analysis62056.TProtocol62056();   //用于解析
            //anaptl.ptlformat.C.RRR = ameter.RecCount;  //接收计数器
            //anaptl.ptlformat.C.SSS = ameter.SendCount;  //发送计数器
            anaptl.RRR = ameter.RecCount;  //接收计数器
            anaptl.SSS = ameter.SendCount;  //发送计数器 hxh

            anaptl.ptlformat.Apdu.rwflag = rwflag;//把请求的应用类型传进去,便于解密应用数据时调用哪个接口
            anaptl.ptlformat.Apdu.encryption = ameter.EncParams; //hxh 2018-5-24                   
            anaptl.ptlformat.Apdu.rwtype = rwtype; //读写选择类型
            try
            {
                anaptl.ptlformat.Apdu.ApduSize = int.Parse(ameter.APDUSize); //hxh 2018-5-16
            }
            catch (Exception ex)
            {
                anaptl.ptlformat.Apdu.ApduSize = PtlConsts.defApduSize;
            }

            if (!string.IsNullOrEmpty(ameter.udpCAddr))  //47协议 udp模式
            {
                anaptl.ptlformat.udpCAddr = ameter.udpCAddr;
                anaptl.ptlformat.udpSAddr = ameter.udpSAddr;
            }

            try
            {
                string ordername = string.Empty;
                //在这里生成用于解析的协议类
                for (int i = 0; i < AttrLst.Count; i++)
                {
                    ProObAttr formatAttr = AttrLst[i].Copy();

                    string aname = AttrLst[i].ProName.Replace("\r", "").Replace("\n", ""); 
                    if (AttrLst[i].proObject != null)
                        aname = AttrLst[i].proObject.ProName.Replace("\r", "").Replace("\n", "")
                              + "->"
                              + aname;
                    ordername += aname;
                    if (i < AttrLst.Count - 1)
                        ordername += ",";

                    //解析后的特殊处理函数
                    if (!string.IsNullOrEmpty(formatAttr.AnaFunc))
                        anaptl.ptlinfo.AnaFunc += formatAttr.AnaFunc
                                                + ",";

                    //传入新的格式
                    bool HaveDataNode = false;  //hxh 2019-4-26 如果没有加入一个数据节点
                    if (formatAttr.ParLst != null && formatAttr.ParLst.Count > 0) //formatAttr.IfReadPars 不能增加这个条件,
                                                                                 //打开方案抄读直接比对的时候需要把parlst带下去,否则底层生成的节点没有inputvalue值
                    {
                        formatAttr.EleLst.Clear();
                        for (int p = 0; p < formatAttr.ParLst.Count; p++)
                            if (formatAttr.ParLst[p].EleNodetype == eleNodeType.Data)
                            {
                                formatAttr.EleLst.Add(formatAttr.ParLst[p].Copy());
                                HaveDataNode = true;
                            }
                    }

                    if (!HaveDataNode)  //hxh 2019-4-26 如果没有加入一个数据节点
                    {
                        PrepareObAttr(formatAttr, rwflag, 0);

                        //重新获取捕获对象加到子节点中                       
                        if (formatAttr.CaptureObjLst != null && formatAttr.CaptureObjLst.Count > 0)
                        {
                            ProObAttr EleArray = new ProObAttr();
                            EleArray.DataType = "structure";
                            EleArray.ProName = "数据记录";
                            foreach (ProObAttr capObj in formatAttr.CaptureObjLst)
                                EleArray.EleLst.Add(capObj);

                            formatAttr.EleLst.Add(EleArray);
                        }
                    }

                    AddFormat(anaptl, formatAttr, true);   //添加格式
                }

                if (!string.IsNullOrEmpty(anaptl.ptlinfo.AnaFunc) && anaptl.ptlinfo.AnaFunc.EndsWith(","))
                    anaptl.ptlinfo.AnaFunc = anaptl.ptlinfo.AnaFunc.Substring(0, anaptl.ptlinfo.AnaFunc.Length - 1);

                anaptl.ptlinfo.DataName = ordername;
            }
            catch (Exception e)
            {
                errorinfo = e.Message;
            }
            return anaptl;
        }


        /// <summary>
        /// 根据读写方式处理对象的节点
        /// </summary>
        /// <param name="obattr"></param>
        /// <param name="rwflag"></param>
        /// <param name="iflag">0:解析用   1:生指令用</param>
        private static void PrepareObAttr(ProObAttr obattr, ClientApduSel rwflag, int iflag)
        {
            switch (iflag)
            {
                case 0: //解析用
                    //设置时，元素用于组织设置数据节点，格式为设置返回的附加数据解析节点；
                    //if (rwflag == ClientApduSel.ActionRequest || rwflag == ClientApduSel.SETRequest)
                    //{
                    //    int count = formatAttr.EleLst.Count;
                    //    for (int j = count - 1; j >= 0; j--)
                    //    {
                    //        if (formatAttr.EleLst[j].AttrMth != AttrType.格式)
                    //            formatAttr.EleLst.Remove(formatAttr.EleLst[j]);
                    //    }
                    //}


                    for (int i = obattr.EleLst.Count - 1; i >= 0; i--)
                    {
                        if (rwflag == ClientApduSel.ActionRequest) //rwflag == ClientApduSel.SETRequest || 操作类的只保留格式，用于设参后的返回数据解析
                        {
                            if (obattr.EleLst[i].AttrMth != AttrType.格式)
                                obattr.RemoveSon(obattr.EleLst[i]);
                        }
                        else  //针对抄读类，要去掉格式节点，用自身子节点作为解析结构
                        {
                            if (obattr.EleLst[i].AttrMth == AttrType.格式)
                                obattr.RemoveSon(obattr.EleLst[i]);
                        }
                    }

                    break;
                case 1: //生指令用
                    //设置时，元素用于组织设置数据节点，格式为设置返回的附加数据解析节点；
                    //if (rwflag == ClientApduSel.ActionRequest || rwflag == ClientApduSel.SETRequest)
                    //{
                    //    int count = formatAttr.EleLst.Count;
                    //    for (int j = count - 1; j >= 0; j--)
                    //    {
                    //        if (formatAttr.EleLst[j].AttrMth == AttrType.格式)
                    //            formatAttr.EleLst.Remove(formatAttr.EleLst[j]);
                    //    }
                    //}


                    for (int i = obattr.EleLst.Count - 1; i >= 0; i--)
                    {
                        if (obattr.EleLst[i].AttrMth == AttrType.格式)
                            obattr.RemoveSon(obattr.EleLst[i]);
                    }
                    break;
            }

            //递归一下
            for (int i = obattr.EleLst.Count - 1; i >= 0; i--)
                PrepareObAttr(obattr.EleLst[i], rwflag, iflag);
        }


        /// <summary>
        /// 根据OBIS获取格式
        /// </summary>
        /// <param name="obattr"></param>
        private static void GetOBISFormat(ProObAttr obattr)
        {
            for (int e = 0; e < obattr.EleLst.Count; e++)
            {
                ProObAttr eleAttr = obattr.EleLst[e];
                if (e == 0 && eleAttr.inputValue == "0")  //CSD个数为0  需要加载所有列
                {
                    if (obattr.ParentAttr.EleLst.Count > 0)
                    {
                        ProObAttr parEleAttr = obattr.ParentAttr.EleLst[0];  //取上一次记录的格式
                        eleAttr.inputValue = parEleAttr.EleLst.Count.ToString();
                        for (int i = 0; i < parEleAttr.EleLst.Count; i++)
                        {
                            parEleAttr.EleLst[i].checkState = CheckState.Checked;
                            obattr.EleLst.Add(parEleAttr.EleLst[i]);
                        }
                    }
                    return;
                }


                GetOBISFormat(eleAttr);
            }
        }



        /// <summary>
        /// 生成一个新的EasyDB
        /// </summary>
        /// <returns></returns>
        //public static EasyDb GetNewEasyDB()
        //{
        //    return PtlConsts.easyDb.Copy();
        //}

        /// <summary>
        /// 获取新ID 
        /// </summary>
        /// <returns></returns>
        //public static string GetNewId(string tablename, string fieldname)
        //{
        //    EasyDb PubDB = GetNewEasyDB();
        //    PubDB.Clear();
        //    PubDB.TableName = tablename;
        //    //select ifnull(max(fieldname),1) from
        //    PubDB.SetSelectColumns("max(" + fieldname + ")+1");
        //    DataTable dt = PubDB.Select();
        //    DataRow dr = dt.Rows[0];
        //    if (dr[0].ToString() == "")
        //        return "1";
        //    else
        //        return dr[0].ToString();

        //}

        /// <summary>
        /// 获取新的自增ID 
        /// </summary>
        /// <returns></returns>
        //public static string GetNewAutoId(string tablename)
        //{
        //    EasyDb PubDB = GetNewEasyDB();
        //    PubDB.Clear();
        //    PubDB.TableName = tablename;
        //    PubDB.SetSelectColumns("LAST_INSERT_ROWID()");
        //    DataTable dt = PubDB.Select();
        //    DataRow dr = dt.Rows[0];
        //    if (dr[0].ToString() == "")
        //        return "1";
        //    else
        //        return dr[0].ToString();

        //}



        #region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中
        /// <summary>  
        /// 注意：DataTable中的列需要与数据库表中的列完全一致。
        /// 已自测可用。
        /// </summary>  
        /// <param name="conStr">数据库连接串</param>
        /// <param name="strTableName">数据库中对应的表名</param>  
        /// <param name="dtData">数据集</param>  
        //public static int SqlBulkCopyInsert(SqlConnection conStr, string strTableName, DataTable dtData, ref string errinfo)
        //{
        //    int rs = -1;
        //    try
        //    {
        //        using (SqlBulkCopy sqlRevdBulkCopy = new SqlBulkCopy(conStr))//引用SqlBulkCopy  
        //        {
        //            sqlRevdBulkCopy.DestinationTableName = strTableName;//数据库中对应的表名  
        //            sqlRevdBulkCopy.NotifyAfter = dtData.Rows.Count;//有几行数据  
        //            sqlRevdBulkCopy.WriteToServer(dtData);//数据导入数据库  
        //            sqlRevdBulkCopy.Close();//关闭连接  
        //        }
        //        rs = 1;
        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //    }
        //    return rs;
        //}
        #endregion



        /// <summary>
        /// 获取正则表达式
        /// </summary>
        /// <param name="formtype">数据类型</param>
        /// <param name="format">数据格式</param>
        /// <returns></returns>
        public static string GetMaskStr(string datatype, string format)
        {
            string resultstr = string.Empty;
            for (int i = 0; i < format.Length; i++)
            {
                if (format[i] == '*')
                    resultstr += "[0-9]";
                else
                    resultstr += @"\"
                               + format[i];
            }
            return resultstr;
        }

        
        public static void DoFuncAfterInputValue(ProObAttr obAttr)
        {
            if (!string.IsNullOrEmpty(obAttr.RecFunc)) //hxh 2018-8-21 输入值变化后的函数处理
            {
                string[] funclst = obAttr.RecFunc.Split(';');
                string errinfo = string.Empty;
                for (int f = 0; f < funclst.Length; f++)
                {
                    if (string.IsNullOrEmpty(funclst[f]))
                        continue;
                    FuncAfterInputValue(funclst[f], obAttr, ref errinfo);

                }               
            }
        }
        /// <summary>
        /// 获取选中的属性类,用于在界面上获取选中项通信
        /// </summary>
        /// <param name="objlst">所有对象列表</param>
        /// <param name="RScaler">是否自动读量纲</param>
        /// <returns></returns>
        public static List<ProObAttr> GetSelectObAttr(List<ProObject> objlst, bool RScaler, bool CanInterior)
        {
            List<ProObAttr> sellst = new List<ProObAttr>();
            //GetSelectObAttr(objlst, sellst, RScaler,CanInterior);
            GetSelectObAttrZ(objlst, sellst, RScaler, CanInterior);
            return sellst;
        }


        /// <summary>
        /// 获取选中的属性类,用于在界面上获取选中项通信
        /// </summary>
        /// <returns></returns>
        private static void GetSelectObAttr(List<ProObject> objlst, List<ProObAttr> sellst, bool RScaler, bool CanInterior)
        {
            for (int i = 0; i < objlst.Count; i++)
            {
                ProObject objitem = objlst[i];
                if (objitem.checkState != CheckState.Checked)
                    continue;

                AddObAttr(objitem.AttrLst, sellst, RScaler, CanInterior);

                GetSelectObAttr(objitem.ObjLst, sellst, RScaler, CanInterior);
            }
        }

        private static void GetSelectObAttrZ(List<ProObject> objlst, List<ProObAttr> sellst, bool RScaler, bool CanInterior)
        {
            for (int i = 0; i < objlst.Count; i++)
            {
                ProObject objitem = objlst[i];
                if (objitem.checkState != CheckState.Checked)
                    continue;

                AddObAttr(objitem.AttrLst, sellst, RScaler, CanInterior);
            }
        }

        /// <summary>
        /// 添加符合条件的ObAttr类,用于在界面上获取选中项通信
        /// </summary>
        /// <param name="attrlst"></param>
        private static void AddObAttr(List<ProObAttr> attrlst, List<ProObAttr> sellst, bool RScaler, bool CanInterior)
        {
            for (int j = 0; j < attrlst.Count; j++)
            {
                ProObAttr obAttr = attrlst[j];
                if (!obAttr.IsVisible || obAttr.checkState != CheckState.Checked)
                    continue;

                if (!CanInterior && obAttr.IfInteroir)  //hxh 没有可操作厂内参数权限又为厂内对象的不选中
                    continue;

                if (obAttr.AttrMth == AttrType.属性 || obAttr.AttrMth == AttrType.方法)
                {                   

                    List<ProObAttr> Insertlst = new List<ProObAttr>();
                    InsertPreAttr(obAttr, RScaler, Insertlst);
                    if (Insertlst != null)
                    {
                        foreach (ProObAttr attr in Insertlst)
                            sellst.Add(attr);
                    }

                    sellst.Add(obAttr);
                }
            }
        }

        
        /// <summary>
        /// 显示指定方案的方案项
        /// </summary>
        /// <param name="objlst"></param>
        /// <param name="schema"></param>
        /// <param name="DoAfterSelectObAttr"></param>
        //public static void LoadItemBySchema(Dictionary<string, ProObAttr> DicItem, ProSchema schema, EventAfterSelectObAttr DoAfterSelectObAttr)//List<ProObject> objlst,
        //{

        //    schema.GetSchemaItemLst();
        //    foreach (string id in schema.SchemaItemlst.Keys)
        //    {
        //        if (!DicItem.ContainsKey(id))
        //            continue;
        //        if (DicItem[id].AttrMth == AttrType.属性 || DicItem[id].AttrMth == AttrType.方法)
        //            DicItem[id].checkState = true;
        //        DicItem[id].inputValue = schema.SchemaItemlst[id].DataValue;
        //        DicItem[id].ParLst = schema.SchemaItemlst[id].ParLst;
        //        DicItem[id].SetCheckStatus(true, true, false);
        //        if (DoAfterSelectObAttr != null)
        //            DoAfterSelectObAttr(DicItem[id]);
        //    }
        //   // SetSelectObAttr(objlst, schema.SchemaItemlst, DoAfterSelectObAttr);

        //}
        /// <summary>
        /// 设置选中的属性类, 用于方案的加载
        /// </summary>
        /// <returns></returns>
        //private static void SetSelectObAttr(List<ProObject> objlst, Dictionary<string, ProSchemaItem> schitemlst, EventAfterSelectObAttr DoAfterSelectObAttr)
        //{
        //    for (int i = 0; i < objlst.Count; i++)
        //    {
        //        Application.DoEvents();
        //        ProObject objitem = objlst[i];

        //        SetObAttr(objitem.AttrLst, schitemlst, DoAfterSelectObAttr);

        //        SetSelectObAttr(objitem.ObjLst, schitemlst, DoAfterSelectObAttr);
        //    }
        //}

        /// <summary>
        /// 设置符合条件的ObAttr类, 用于方案的加载
        /// </summary>
        /// <param name="attrlst"></param>
        //private static void SetObAttr(List<ProObAttr> attrlst, Dictionary<string, ProSchemaItem> schitemlst, EventAfterSelectObAttr DoAfterSelectObAttr)
        //{
        //    for (int j = 0; j < attrlst.Count; j++)
        //    {
        //        Application.DoEvents();
        //        ProObAttr obAttr = attrlst[j];
        //        if (!obAttr.IsVisible)
        //            continue;

                
        //        bool rs = ProSchemaItem.FindItemByObAttr(obAttr, schitemlst);
        //        if (rs)
        //        {
        //            obAttr.checkState = true;
        //            obAttr.SetCheckStatus(true, true, false);
        //            if (DoAfterSelectObAttr != null)
        //                DoAfterSelectObAttr(obAttr);

        //        }
        //        SetObAttr(obAttr.EleLst, schitemlst, DoAfterSelectObAttr);
        //    }

        //}
        /// <summary>
        /// 获取选中的属性类, 主要用于方案管理的选中保存
        /// </summary>
        /// <returns></returns>
        //public static void GetSchemaSelectObAttr(Dictionary<string, ProObAttr> DicItem, List<ProObAttr> prolst, bool CanInterior) //List<ProObAttr> prolst,
        //{
        //    foreach (string id in DicItem.Keys)
        //    {
        //        Application.DoEvents();

        //        if (DicItem[id].AttrMth == AttrType.方法 || DicItem[id].AttrMth == AttrType.属性)
        //        {
        //            if (!CanInterior && DicItem[id].IfInteroir)  //hxh 没有可操作厂内参数权限又为厂内对象的不选中
        //                continue;
        //            if (DicItem[id].checkState != true)
        //                continue;
        //            prolst.Add(DicItem[id]);
        //        }
        //        else
        //        {
        //            ProObAttr parentAttr = DicItem[id].ParentAttr;
        //            while (parentAttr != null && parentAttr.AttrMth > AttrType.方法)
        //                parentAttr = parentAttr.ParentAttr;

        //            if (parentAttr.checkState == true)
        //                prolst.Add(DicItem[id]);
        //        }

        //    }
        //}
        /// <summary>
        /// 获取选中的属性类, 主要用于方案管理的选中保存
        /// </summary>
        /// <returns></returns>
        //public static void GetSchemaSelectObAttr(List<ProObject> objlst, List<ProObAttr> prolst, bool CanInterior)
        //{
        //    for (int i = 0; i < objlst.Count; i++)
        //    {
        //        Application.DoEvents();
        //        ProObject objitem = objlst[i];
        //        if (objitem.checkState != true)
        //            continue;

        //        AddSchemaObAttr(objitem.AttrLst, prolst, CanInterior);

        //        GetSchemaSelectObAttr(objitem.ObjLst, prolst, CanInterior);
        //    }
        //}
        /// <summary>
        /// 添加符合条件的ObAttr类, 主要用于方案管理的选中保存
        /// </summary>
        /// <param name="attrlst"></param>
        //private static void AddSchemaObAttr(List<ProObAttr> attrlst, List<ProObAttr> prolst, bool CanInterior)
        //{
        //    for (int j = 0; j < attrlst.Count; j++)
        //    {
        //        Application.DoEvents();
        //        ProObAttr obAttr = attrlst[j];
        //        if (obAttr.checkState != true)
        //            continue;
        //        if (!CanInterior && obAttr.IfInteroir)  //hxh 没有可操作厂内参数权限又为厂内对象的不选中
        //            continue;
        //        prolst.Add(obAttr);
        //        // GetApdu(obAttr);  //hxh  生成APDU                
        //        AddSchemaElement(obAttr.EleLst, prolst);

        //    }
        //}
        /// <summary>
        /// 添加属性下面的元素,不用判断选择状态或是否可见，都需保存, 主要用于方案管理的选中保存
        /// </summary>
        /// <param name="attrlst"></param>
        //private static void AddSchemaElement(List<ProObAttr> attrlst, List<ProObAttr> prolst)
        //{
        //    for (int j = 0; j < attrlst.Count; j++)
        //    {
        //        Application.DoEvents();
        //        ProObAttr obAttr = attrlst[j];
        //        prolst.Add(obAttr);
        //        AddSchemaElement(obAttr.EleLst, prolst);
        //    }
        //}

        #region 建链接相关对象
        public static List<ProObAttr> GetDLLConnectAttr(TMeter62056 Meter, ref string errinfo)
        {
            try
            { //生成要读取对象的列表
                List<ProObAttr> AttrLst = new List<ProObAttr>();

                //应用连接对象
                ProObject proObject = new ProObject();
                proObject.checkState = CheckState.Checked;
                proObject.ObName = "建立链路层_连接";

                ProObAttr connAttr = new ProObAttr();
                connAttr.proObject = proObject;
                connAttr.checkState = CheckState.Checked;
                connAttr.AttrMth = AttrType.属性;
                connAttr.ProName = proObject.ObName;
                proObject.AttrLst.Add(connAttr);
                AttrLst.Add(connAttr);

                //生成应用连接对象下的属性
                ProObAttr eleAttr = new ProObAttr();

                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "发送最大信息域长度";
                eleAttr.inputValue = Meter.SendMaxSize;
                connAttr.EleLst.Add(eleAttr);

                eleAttr = new ProObAttr();
                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "接收最大信息域长度";
                eleAttr.inputValue = Meter.RecMaxSize;
                connAttr.EleLst.Add(eleAttr);

                eleAttr = new ProObAttr();
                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "发送窗口尺寸";
                eleAttr.inputValue = Meter.SendMaxWindow;
                connAttr.EleLst.Add(eleAttr);

                eleAttr = new ProObAttr();
                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "接收窗口尺寸";
                eleAttr.inputValue = Meter.RecMaxWindow;
                connAttr.EleLst.Add(eleAttr);

                return AttrLst;

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                return null;
            }

        }




        public static List<ProObAttr> GetCosemConnectAttr(TMeter62056 Meter, ref string errinfo)
        {
            try
            { //生成要读取对象的列表
                List<ProObAttr> AttrLst = new List<ProObAttr>();

                //应用连接对象
                ProObject proObject = new ProObject();
                proObject.checkState = CheckState.Checked;
                proObject.ObName = "建立应用层_连接";

                ProObAttr connAttr = new ProObAttr();
                connAttr.proObject = proObject;
                connAttr.checkState = CheckState.Checked;
                connAttr.AttrMth = AttrType.属性;
                connAttr.ProName = proObject.ObName;
                proObject.AttrLst.Add(connAttr);
                AttrLst.Add(connAttr);

                //生成应用连接对象下的属性
                ProObAttr eleAttr = new ProObAttr();

                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "Application-context-name";
                eleAttr.inputValue = Meter.ContextName.ToString(); //使用逻辑名还是短名，是否加密
                connAttr.EleLst.Add(eleAttr);

                eleAttr = new ProObAttr();
                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "MechanismName";
                eleAttr.inputValue = Meter.SecurityMode.ToString();//是否用安全级别，如果用认证级别，则包含子节点密码

                ProObAttr ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "AuthenValue";
                ele.inputValue = Meter.SecurityPassWord;//包含子节点密码
                if (Meter.SecurityMode >= Authentication.HLS)
                {
                    Meter.EncParams.CtoS = (Guid.NewGuid().ToString()).Substring(0, 8);
                    ele.inputValue = Meter.EncParams.CtoS;// "高级认证所需随机数";
                }
                eleAttr.EleLst.Add(ele);
                connAttr.EleLst.Add(eleAttr);

                eleAttr = new ProObAttr();
                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "AA_UserInfo"; //用户信息节点，包含下面几个子节点

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "Conformance";
                ele.inputValue = Meter.ProConform;//一致性数据
                eleAttr.EleLst.Add(ele);

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "RecSize";
                ele.inputValue = Meter.RecMaxSize;//服务端接收尺寸大小
                eleAttr.EleLst.Add(ele);
                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "SendSize";
                ele.inputValue = Meter.SendMaxSize;//服务端发送尺寸大小
                eleAttr.EleLst.Add(ele);
                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "VerNumber";
                ele.inputValue = Meter.AppProVersion;//协议版本
                eleAttr.EleLst.Add(ele);

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "Quality";
                ele.inputValue = "";//
                eleAttr.EleLst.Add(ele);

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "DedicatedKey";
                ele.inputValue = Meter.DedicatedKey;//密钥 
                eleAttr.EleLst.Add(ele);

                connAttr.EleLst.Add(eleAttr);

                return AttrLst;

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                return null;
            }

        }

        public static List<ProObAttr> GetHLSAuthenAttr(TMeter62056 Meter, ref string errinfo)
        {
            try
            {    //生成回答HLS身份验证数据的列表
                List<ProObAttr> AttrLst = new List<ProObAttr>();

                //回答HLS身份验证数据
                ProObject proObject = new ProObject();
                proObject.checkState = CheckState.Checked;
                proObject.ObName = "";
                proObject.proClass.ClassID = "15";
                proObject.OBIS = Meter.MTRole.LNOBIS;// PtlConsts.AssLNOBIS;

                ProObAttr connAttr = new ProObAttr();
                connAttr.proObject = proObject;
                connAttr.checkState = CheckState.Checked;
                connAttr.OBIS = proObject.OBIS;
                connAttr.AttrMth = AttrType.方法;
                connAttr.Seq = 1;
                connAttr.ProName = "HLS身份验证_连接";
                connAttr.DataType = enumData.octet_string.ToString();
                connAttr.DataLen = "0";
                connAttr.inputValue = Meter.EncParams.StoC; //由应用连接的第一步返回已经过加密了的数据
                proObject.AttrLst.Add(connAttr);
                AttrLst.Add(connAttr);

                return AttrLst;

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                return null;
            }
        }

        public static List<ProObAttr> GetFrameCountAttr(TMeter62056 Meter, ref string errinfo)
        {
            try
            {    //取得表中计数器
                List<ProObAttr> AttrLst = new List<ProObAttr>();


                ProObject proObject = new ProObject();
                proObject.checkState = CheckState.Checked;
                proObject.ObName = "";
                proObject.proClass.ClassID = "1";
                if (Meter.MeterCommAddr == PtlConsts.BrOBISCastAddr1 ||
                    Meter.MeterCommAddr == PtlConsts.BrOBISCastAddr2)
                    proObject.OBIS = PtlConsts.BkeyFCOBIS;
                else
                    proObject.OBIS = Meter.MTRole.ICOBIS;// PtlConsts.UkeyFCOBIS;//"0.5.43.1.0.255";

                ProObAttr connAttr = new ProObAttr();
                connAttr.proObject = proObject;
                connAttr.checkState = CheckState.Checked;
                connAttr.OBIS = proObject.OBIS;
                connAttr.AttrMth = AttrType.属性;
                connAttr.Seq = 2;
                connAttr.ProName = "帧计数器_连接"; //"Receive frame counter";
                proObject.AttrLst.Add(connAttr);
                AttrLst.Add(connAttr);

                return AttrLst;

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                return null;
            }
        }

        public static List<ProObAttr> GetCosemDisConnectAttr(TMeter62056 Meter, ref string errinfo)
        {
            try
            { //生成要读取对象的列表
                List<ProObAttr> AttrLst = new List<ProObAttr>();

                //应用连接对象
                ProObject proObject = new ProObject();
                proObject.checkState = CheckState.Checked;
                proObject.ObName = "断开应用连接";

                ProObAttr connAttr = new ProObAttr();
                connAttr.proObject = proObject;
                connAttr.checkState = CheckState.Checked;
                connAttr.AttrMth = AttrType.属性;
                connAttr.ProName = proObject.ObName;
                proObject.AttrLst.Add(connAttr);
                AttrLst.Add(connAttr);

                //生成应用连接对象下的属性
                ProObAttr eleAttr = new ProObAttr();

                eleAttr = new ProObAttr();

                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "Reason"; //
                eleAttr.inputValue = ((int)DicReqReason.Normal).ToString();  //固定为Normal
                connAttr.EleLst.Add(eleAttr);

                eleAttr.proObject = proObject;
                eleAttr.checkState = CheckState.Checked;
                eleAttr.AttrMth = AttrType.元素;
                eleAttr.ProName = "AA_UserInfo"; //用户信息节点，包含下面几个子节点

                ProObAttr ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "Conformance";
                ele.inputValue = Meter.ProConform;//一致性数据
                eleAttr.EleLst.Add(ele);

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "RecSize";
                ele.inputValue = Meter.RecMaxSize;//服务端接收尺寸大小
                eleAttr.EleLst.Add(ele);
                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "SendSize";
                ele.inputValue = Meter.SendMaxSize;//服务端发送尺寸大小
                eleAttr.EleLst.Add(ele);
                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "VerNumber";
                ele.inputValue = Meter.AppProVersion;//协议版本
                eleAttr.EleLst.Add(ele);

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "Quality";
                ele.inputValue = "";//
                eleAttr.EleLst.Add(ele);

                ele = new ProObAttr();
                ele.proObject = proObject;
                ele.checkState = CheckState.Checked;
                ele.AttrMth = AttrType.元素;
                ele.ProName = "DedicatedKey";
                ele.inputValue = Meter.DedicatedKey;//密钥 
                eleAttr.EleLst.Add(ele);

                connAttr.EleLst.Add(eleAttr);

                return AttrLst;

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                return null;
            }

        }
        #endregion


        #region 特殊处理函数
        /// <summary>
        /// 初始化特殊函数列表
        /// </summary>
        public static void InitSpecialFunc()
        {
            try
            {
                SpecialFuncLst.Add("刷新关联对象", "RefreshCaptureObjs");
                SpecialFuncLst.Add("刷新属性单位及换算", "RefreshScalerUnit");
                SpecialFuncLst.Add("输入值刷新到元素CHOICE值", "RefreshInputChoice");
                SpecialFuncLst.Add("抄读单位及换算", "ReadScalerUnit");
                SpecialFuncLst.Add("抄读另一个属性", "ReadOtherObattr");
                SpecialFuncLst.Add("刷新抄读条件值", "RefreshReadPar");
                SpecialFuncLst.Add("刷新数据库对象列表", "RefreshObjList");
                SpecialFuncLst.Add("刷新其他属性的数据类型", "RefreshOtherObattrType");
            }
            catch (Exception ex) { }
        }

        /// <summary>
        /// 输入值变化后的特殊处理
        /// </summary>
        /// <param name="funcname">函数名</param>
        /// <param name="par1">参数</param>
        /// <param name="errinfo">回传错误信息</param>
        /// <returns></returns>
        public static int FuncAfterInputValue(string funcname, ProObAttr attr, ref string errinfo)
        {
            int rs = 0;
            string realfuncname = string.Empty;
            try
            {
                string parstr = string.Empty;  //函数中带的参数
                if (funcname.IndexOf(":") > 0)
                {
                    parstr = funcname.Substring(funcname.IndexOf(":") + 1);
                    funcname = funcname.Substring(0, funcname.IndexOf(":"));

                    if (!SpecialFuncLst.ContainsKey(funcname))
                    {
                        errinfo = "输入值变化后的处理出现异常,未知的函数名:"
                                + funcname;
                        return -1;
                    }
                    realfuncname = (string)SpecialFuncLst[funcname];
                }

                object ha = Activator.CreateInstance(typeof(PubFunc62056), true);
                PubFunc62056 pubfunction = ha as PubFunc62056;
                MethodInfo method = pubfunction.GetType().GetMethod(realfuncname);
                method.Invoke(pubfunction, new object[] { attr, parstr });
                rs = 1;
            }
            catch (Exception e)
            {
                rs = -1;
                errinfo = "输入值变化后的处理出现异常,函数名:"
                        + funcname
                        + ",原因:";
                if (e.InnerException == null)
                    errinfo += e.Message;
                else
                    errinfo += e.InnerException.Message;
            }
            return rs;
        }

        /// <summary>
        /// 解析后的特殊处理
        /// </summary>
        /// <param name="funcname">函数名</param>
        /// <param name="par1">参数</param>
        /// <param name="errinfo">回传错误信息</param>
        /// <returns></returns>
        public static int FuncAfterAna(TMeter62056 Meter62056, string funcname, ProObAttr attr, CosemObject oiObj, List<CosemObject> oiObjLst, ref string errinfo)  //hxh 2017-3-21
        {
            int rs = 0;
            string realfuncname = string.Empty;
            try
            {
                string parstr = string.Empty;  //函数中带的参数
                if (funcname.IndexOf(":") > 0)
                {
                    parstr = funcname.Substring(funcname.IndexOf(":") + 1);
                    funcname = funcname.Substring(0, funcname.IndexOf(":"));

                    if (!SpecialFuncLst.ContainsKey(funcname))
                    {
                        errinfo = "解析后的处理出现异常,未知的函数名:"
                                + funcname;
                        return -1;
                    }
                    realfuncname = (string)SpecialFuncLst[funcname];
                }

                object ha = Activator.CreateInstance(typeof(PubFunc62056), true);
                PubFunc62056 pubfunction = ha as PubFunc62056;
                MethodInfo method = pubfunction.GetType().GetMethod(realfuncname);
                method.Invoke(pubfunction, new object[] { Meter62056, parstr, attr, oiObj, oiObjLst });
                rs = 1;
            }
            catch (Exception e)
            {
                rs = -1;
                errinfo = "解析后的处理出现异常,函数名:"
                        + funcname
                        + ",原因:";
                if (e.InnerException == null)
                    errinfo += e.Message;
                else
                    errinfo += e.InnerException.Message;
            }
            return rs;
        }


        #endregion




        #region  解析后执行
        /// <summary>
        /// 刷新数据库对象列表
        /// </summary>
        /// <param name="Meter62056"></param>
        /// <param name="parstr"></param>
        /// <param name="attr"></param>
        /// <param name="oiObj"></param>
        /// <param name="oiObjLst"></param>
        //public void RefreshObjList(TMeter62056 Meter62056, string parstr, ProObAttr attr, CosemObject oiObj, List<CosemObject> oiObjLst)
        //{
        //    try
        //    {
        //        List<ElementData> eleNodeList = oiObj.DataNode.eleNodeList;
        //        if (oiObj.result != null && oiObj.result != "0") // 对象解析结果有错误信息则不执行更新
        //            return;

        //        if (eleNodeList.Count == 0)
        //            return;

        //        ProObject.RefreshObjLstByReadLst(eleNodeList);

        //        //执行UI层刷新委托  shaunwang 2019-7-9
        //        if (doReloadObj != null)
        //            doReloadObj(ProObject.GetTreeObjLst(false));
        //    }
        //    catch (Exception e)
        //    {
        //        throw new Exception("刷新关联对象异常:" + e.Message);
        //    }

        //}
        /// <summary>
        /// 刷新关联对象
        /// </summary>
        /// <param name="attr"></param>
        /// <param name="ptlinfo"></param>        
        //public void RefreshCaptureObjs(TMeter62056 Meter62056, string parstr, ProObAttr attr, CosemObject oiObj, List<CosemObject> oiObjLst)
        //{
        //    try
        //    {
        //        if (oiObj.result != "0") return; // 对象解析结果有错误信息则不执行更新
        //        ProObAttr DesAttr = attr.proObject.AttrLst[int.Parse(parstr) - 1];
        //        for (int i = 0; i < attr.proObject.AttrLst.Count; i++)
        //        {
        //            if (attr.proObject.AttrLst[i].Seq == int.Parse(parstr))
        //            {
        //                DesAttr = attr.proObject.AttrLst[i];
        //                break;
        //            }
        //        }
        //        string Attrid = DesAttr.ID;
        //        ProCaptureObj.RemoveEleItem(Attrid);

        //        //清空数据库中原方案项
        //        PtlConsts.easyDb.BeginTrans();
        //        if (ProCaptureObj.DeleteItemByAttrID(Attrid, false) < 0)
        //        {
        //            PtlConsts.easyDb.RollbackTrans();
        //            throw new Exception("刷新关联对象异常:" + "清空原关联对象失败");
        //        }

        //        List<ElementData> eleNodeList = oiObj.DataNode.eleNodeList;
        //        int rs = FindObjForSch(eleNodeList, DesAttr);
        //        if (rs < 0)
        //        {
        //            PtlConsts.easyDb.RollbackTrans();
        //            throw new Exception("刷新关联对象异常:" + "添加新关联对象失败");
        //        }

        //        PtlConsts.easyDb.CommitTrans();
        //        //attr = ProObAttr.GetAttrByID(Attrid);
        //        //attr.CaptureObjLst = ProObAttr.GetCaptureObjByAttr(parstr);                  

        //    }
        //    catch (Exception e)
        //    {
        //        throw new Exception("刷新关联对象异常:" + e.Message);
        //    }
        //}


        /// <summary>
        /// 刷新对象的换算和单位
        /// </summary>
        /// <param name="attr"></param>
        /// <param name="ptlinfo"></param>        
        public void RefreshScalerUnit(TMeter62056 Meter62056, string parstr, ProObAttr attr, CosemObject oiObj, List<CosemObject> oiObjLst)
        {
            try
            {
                if (oiObj.result != "0") return; // 对象解析结果有错误信息则不执行更新

                string[] idList = parstr.Split(',');
                string[] scalerunit = oiObj.DataNode.ReadValue.Split(',');
                string scaler = scalerunit[0];
                string unit = scalerunit[1];
                if (oiObj.DataNode.DataType == enumData.structure.ToString() && //根据抄读回的CAD查找对应的对象，取其单位及换算
                    oiObj.DataNode.DataTypeDIY != enumData.ScalerUnit.ToString())
                {
                    List<ElementData> elelst = oiObj.DataNode.eleNodeList;
                    if (elelst[1].DataTypeDIY != enumData.OBIS.ToString())
                    {
                        string errorinfo = "";
                        string framevalue = elelst[1].FrameValue;
                        OBIS.AnalizeData(ref framevalue, elelst[1], ref errorinfo);
                    }
                    string sCAD = elelst[0].ReadValue + '.' + //classid
                                  elelst[1].ReadValue + '.' + //OBIS
                                  elelst[2].ReadValue;//seq
                    if (elelst.Count > 3)
                        sCAD += '.' + elelst[3].ReadValue;   //eleSeq
                    else
                        sCAD += ".0";
                   
                    ProObAttr ObAttr = ProObAttr.GetAttrByCAD(sCAD, AttrType.属性.ToString());
                    elelst[1].ValueName = ObAttr.ProName;
                    scaler = ObAttr.Scaler;
                    unit = ObAttr.Units;
                }
                
                for (int i = 0; i < idList.Length; i++)
                {
                    ProObAttr tmpattr = attr.proObject.AttrLst[int.Parse(idList[i]) - 1];
                    tmpattr.Scaler = scaler;
                    tmpattr.Units = unit;   //更新协议本身的量钢

                    //ProObAttr.UpdateSalerUnit(tmpattr.ID, scaler, unit); //更新到数据库

                    //更新解析后对象中其他相关CosemObject
                    for (int j = 0; j < oiObjLst.Count; j++)
                    {
                        CosemObject aObj = oiObjLst[j];
                        if (aObj.classid == attr.proObject.proClass.ClassID 
                            && aObj.OBIS == attr.OBIS 
                            && aObj.AttrSeq == idList[i]
                            && aObj.Tag != null)
                        {
                            if (aObj.DataNode.Scaler != scaler || aObj.DataNode.Units != unit)
                                aObj.DataNode.UpdateScalerUnit(scaler, unit);                      
                            break;                           
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("刷新换算和单位异常:" + e.Message);
            }
        }


        /// <summary>
        /// 将抄读返回的对象的数据类型刷新到其他属性的数据类型   比如class 21 中的抄读monitored_value后找到对象  刷新thresholds子节点的数据类型
        /// </summary>
        /// <param name="attr"></param>
        /// <param name="ptlinfo"></param>        
        public void RefreshOtherObattrType(TMeter62056 Meter62056, string parstr, ProObAttr attr, CosemObject oiObj, List<CosemObject> oiObjLst)
        {
            try
            {
                if (oiObj.result != "0") return; // 对象解析结果有错误信息则不执行更新

                string[] idList = parstr.Split(',');
                string datatype = "";
                if (oiObj.DataNode.DataType == enumData.structure.ToString()) //根据抄读回的CAD查找对应的对象，取其数据类型
                {
                    List<ElementData> elelst = oiObj.DataNode.eleNodeList;
                    if (elelst.Count < 3 || elelst[1].DataType != enumData.OBIS.ToString())
                        return;
                    string sCAD = elelst[0].ReadValue + '.' + //classid
                                  elelst[1].ReadValue + '.' + //OBIS
                                  elelst[2].ReadValue;//seq

                    ProObAttr ObAttr = ProObAttr.GetAttrByCAD(sCAD, AttrType.属性.ToString());
                    if (ObAttr != null)
                        datatype = ObAttr.DataType.ToString();
                }

                for (int i = 0; i < idList.Length; i++)
                {
                    ProObAttr tmpattr = attr.proObject.AttrLst[int.Parse(idList[i]) - 1];
                    if (!string.IsNullOrEmpty(datatype))
                    {
                        tmpattr.DataType = datatype;  //更新协议本身的数据类型

                        //ProObAttr.UpdateDataType(tmpattr.ID, datatype); //更新到数据库
                    }

                }
            }
            catch (Exception e)
            {
                throw new Exception("刷新换算和单位异常:" + e.Message);
            }
        }
        #endregion

        /// <summary>
        /// 输入值刷新到元素CHOICE值，把第一个参数标示对象的输入值赋给第二个参数标示对象的inputValue              
        /// </summary>
        /// <param name="Meter62056"></param>
        /// <param name="parstr"></param>
        /// <param name="attr"></param>
        /// <param name="oiObj"></param>
        public void RefreshInputChoice(ProObAttr attr, string parstr)
        {
            try
            {
                int ichoice = MyConvert.getInt32(attr.InputToFrame());
                int eleSeq = MyConvert.getInt32(parstr); //
                if (attr.ParentAttr == null) return;


                ProObAttr desAttr = attr.ParentAttr.EleLst[eleSeq - 1];
                desAttr.inputValue = ichoice.ToString();
                for (int i = 0; i < desAttr.EleLst.Count; i++)
                {
                    if (i == ichoice)
                        desAttr.EleLst[i].Availability = true;
                    else
                        desAttr.EleLst[i].Availability = false;
                }
                //attr = desAttr;
            }
            catch (Exception e)
            {
                throw new Exception("输入值刷新到元素CHOICE值异常:" + e.Message);
            }
        }


        public void RefreshReadPar(TMeter62056 Meter62056, string parstr, ProObAttr attr, CosemObject oiObj)
        {
            try
            {
                if (oiObj.result != "0") return; // 对象解析结果有错误信息则不执行更新                
               
                int attrSeq = MyConvert.getInt32(parstr);
                ProObject proobject = attr.GetProObject();
                if (proobject == null) return;

                ProObAttr desAttr = null;
                foreach (ProObAttr obattr in proobject.AttrLst)
                    if (obattr.Seq == attrSeq)
                    {
                        desAttr = obattr;
                        break;
                    }
               
                for (int i = 0; i < desAttr.ParLst.Count; i++)
                {
                    if (desAttr.ParLst[i].EleNodetype == eleNodeType.AppendPar) {
                        if (desAttr.ParLst[i].EleLst[1].inputValue == "-1")
                            desAttr.ParLst[i].EleLst[1].inputValue = oiObj.DataNode.ReadValue;
                        break;
                    }
                   
                }
            }
            catch (Exception e)
            {
                throw new Exception("刷新CHOCE元素信息异常:" + e.Message);
            }
        }

        ///// <summary>
        ///// 刷新CHOCE元素信息,根据输入参数取第一个参数对应的对象抄读值，取第二个参数标示的对象对应的元素节点，更换名称，换算单位等信息
        ///// </summary>
        ///// <param name="Meter62056"></param>
        ///// <param name="parstr"></param>
        ///// <param name="attr"></param>
        ///// <param name="oiObj"></param>
        //public void RefreshChoiceEle(TMeter62056 Meter62056, string parstr, ProObAttr attr, CosemObject oiObj)
        //{
        //    try
        //    {
        //        if (oiObj.result != "0") return; // 对象解析结果有错误信息则不执行更新                
        //        int ichoice =MyConvert.getInt32(oiObj.DataNode.ReadValue);
        //        int eleSeq = MyConvert.getInt32(parstr);
        //        if (attr.ParentAttr == null) return;

        //        ProObAttr desAttr = attr.ParentAttr.EleLst[eleSeq - 1];
        //        for (int i = 0; i < desAttr.EleLst.Count; i++)
        //        {
        //            if(i>=oiObj.DataNode.eleNodeList.Count) return;
        //            ElementData eleData = oiObj.DataNode.eleNodeList[i];                     
        //            eleData.Tag = desAttr.EleLst[i];
        //            eleData.ValueName=desAttr.EleLst[i].ProName;
        //            eleData.Scaler = desAttr.EleLst[i].Scaler;
        //            eleData.Units = desAttr.EleLst[i].Units;                     
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        throw new Exception("刷新CHOCE元素信息异常:") + e.Message);
        //    }
        //}

        /// <summary>
        /// 查找OAD类型节点并添加到元素方案表
        /// </summary>
        /// <param name="elelst"></param>
        /// <param name="schid"></param>
        private int FindObjForSch(List<ElementData> elelst, ProObAttr DesAttr)
        {
            int rs = 0;
            if (elelst == null)
                return 1;
            try
            {
                // DesAttr.CaptureObjLst.Clear();
                int iseq = ProCaptureObj.GetEleCountBySch(DesAttr.ID);//取得数据库中存在与此ID关联的已有关联对象数, 有些固定项不会被删除
                string sCAD = "";               
                for (int e = 0; e < elelst.Count; e++)
                {
                    if (rs < 0)
                        return rs;
                    iseq++;
                    //capture_object_definition ::= structure
                    //{
                    //class_id: long-unsigned,
                    //logical_name: octet-string,
                    //attribute_index: integer,
                    //data_index: long-unsigned
                    //}                 
                    if (elelst[e].eleNodeList[1].DataTypeDIY != enumData.OBIS.ToString())
                    {
                        string errorinfo = "";
                        string framevalue = elelst[e].eleNodeList[1].FrameValue;
                        OBIS.AnalizeData(ref framevalue, elelst[e].eleNodeList[1], ref errorinfo);
                    }
                    sCAD = elelst[e].eleNodeList[0].ReadValue + '.' + //classid
                                  elelst[e].eleNodeList[1].ReadValue + '.' + //OBIS
                                  elelst[e].eleNodeList[2].ReadValue;//seq
                    if (elelst[e].eleNodeList.Count > 3)
                        sCAD += '.' + elelst[e].eleNodeList[3].ReadValue;   //eleSeq
                    else
                        sCAD += ".00";

                                 
                  
                    ProObAttr ObAttr = ProObAttr.GetAttrByCAD(sCAD, AttrType.属性.ToString());// GetCaptrueAttrByCAD(sCAD);

                    ProCaptureObj newitem = new ProCaptureObj();

                    if (ObAttr == null)
                    {
                       // ObAttr = new ProObAttr();
                      //  elelst[e].ValueName = elelst[e].eleNodeList[1].ReadValue;
                        newitem.RelateAttrID = elelst[e].eleNodeList[1].ReadValue;
                    }
                    else
                    {
                        elelst[e].ValueName = ObAttr.ProName; //把关联对象各称赋过去显示
                        if (ObAttr.ProName.ToUpper() == "value".ToUpper())
                            elelst[e].ValueName = ObAttr.GetProObject().ObName + "-" + ObAttr.ProName;
                        newitem.RelateAttrID = ObAttr.ID;
                    }
                    
                    newitem.ObAttrID = DesAttr.ID;                   
                        
                    newitem.IfStatic = false;
                    newitem.DataIndex = int.Parse(elelst[e].eleNodeList[3].ReadValue);
                    newitem.Seq = iseq;
                    rs = newitem.SaveEleItem(true);//保存至数据库                       
                    if (rs < 0)
                        return rs;

                }

            }
            catch (Exception e)
            {
                rs = -1;
            }
            return rs;
        }


        public static string AccessStrToWord(string sAccess, int AMflag)
        {
            StringBuilder stbAccess = new StringBuilder();
            string[] strlist = null;
            if (AMflag == (int)AttrType.属性)
                strlist = Enum.GetNames(typeof(TAttrAccess));
            else
                if (AMflag == (int)AttrType.方法)
                    strlist = Enum.GetNames(typeof(TMthAccess));
                else
                    return string.Empty;

            for (int i = strlist.Length - 1; i >= 0; i--)
            {
                if (sAccess.Contains(strlist[i]))
                    stbAccess.Append("1");
                else
                    stbAccess.Append("0");
            }
            return MyConvert.BinToHex(stbAccess.ToString(), 2);

        }

        public static string WordToAccessStr(string sWord, int AMflag)
        {

            string[] strlist = null;
            List<string> Accesslist = new List<string>();
            if (AMflag == (int)AttrType.属性)
                strlist = Enum.GetNames(typeof(TAttrAccess));
            else
                if (AMflag == (int)AttrType.方法)
                    strlist = Enum.GetNames(typeof(TMthAccess));
                else
                    return string.Empty;

            string binAccess = MyConvert.HexToBin(sWord);
            if (string.IsNullOrEmpty(binAccess)) return sWord;

            for (int i = strlist.Length - 1; i >= 0; i--)
            {
                if (binAccess[7 - i] == '1')
                    Accesslist.Add(strlist[i]);
            }
            return string.Join(",", Accesslist.ToArray());

        }

        public static void SetEncParameters(TMeter62056 ameter, string sInifile)
        {
            //sInifile = Application.StartupPath + "\\" + sInifile;
            ameter.FactoryCode =  "WSE";
            //ameter.IC = RWOutFiles.GetINIString(sInifile, "EncryptedData", "IC", "00000001");
            ameter.MasterKey = "00112233445566778899AABBCCDDEEFF";
            ameter.EncryptedKey = "000102030405060708090A0B0C0D0E0F";
            ameter.BroadcastEKey = "00112233445566778899AABBCCDDEEFF";
            ameter.AuthenKey = "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF";
            ameter.DedicatedKey =  "";
        }

        public static void InsertPreAttr(ProObAttr obattr, bool ifRScaler, List<ProObAttr> frmAttrLst)
        {
            try
            {
                obattr.GetCaptureObjByAttr(); //搜捕获对象里是否有要抄量钢的
                if (ifRScaler) //&& string.IsNullOrEmpty(obattr.SendFunc)
                {                 
                    for (int i = 0; i < obattr.CaptureObjLst.Count; i++) {
                        InsertPreAttr(obattr.CaptureObjLst[i], ifRScaler, frmAttrLst);
                    }
                }
                if (string.IsNullOrEmpty(obattr.SendFunc))
                    return;

                string[] funclst = obattr.SendFunc.Split(';');

                for (int f = 0; f < funclst.Length; f++)
                {
                    string errinfo = string.Empty;
                    string funcname = string.Empty;
                    string parstr = string.Empty;
                    ProObAttr Insertobattr = null;
                    if (string.IsNullOrEmpty(funclst[f]))
                        continue;
                    if (funclst[f].IndexOf(":") > 0)
                    {
                        parstr = funclst[f].Substring(funclst[f].IndexOf(":") + 1); 
                        funcname = funclst[f].Substring(0, funclst[f].IndexOf(":"));

                        if (!SpecialFuncLst.ContainsKey(funcname))
                        {
                            errinfo = "发送前的处理出现异常,未知的函数名:"
                                    + funcname;
                        }
                        funcname = (string)SpecialFuncLst[funcname];
                    }
                    switch (funcname) { 
                        case "ReadScalerUnit":
                            if (ifRScaler && obattr.GetProObject().AttrLst.Count >= int.Parse(parstr))
                            {
                                Insertobattr = obattr.proObject.AttrLst[int.Parse(parstr) - 1].Copy();
                                Insertobattr.Availability = false; //解析界面不显示
                                frmAttrLst.Add(Insertobattr);
                            }
                            break;
                        case "ReadOtherObattr":
                            if (obattr.proObject.AttrLst.Count >= int.Parse(parstr))
                            {
                                foreach (ProObAttr attr in obattr.GetProObject().AttrLst)
                                    if (attr.Seq == int.Parse(parstr))
                                    {
                                        Insertobattr = attr.Copy();
                                        break;
                                    }
                                if (Insertobattr != null)
                                {
                                    Insertobattr.Availability = false; //解析界面不显示
                                    frmAttrLst.Add(Insertobattr);
                                }
                            }
                            break;
                    }                    
                }
               // return frmAttrLst;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

        }


        /// <summary>
        /// 格式化OBIS，若分隔符为0，则只去掉空格全部转成大写
        /// </summary>
        /// <param name="OBIS"></param>
        /// <param name="DesSplit"></param>
        /// <returns></returns>
        public static string FormatOBIS(string OBIS, char DesSplit)
        {
            if (DesSplit == '0')
                return OBIS.Replace(" ", "").ToUpper();
            else
                return OBIS.Replace(':', DesSplit).Replace('-', DesSplit).Replace(',', DesSplit).Replace(" ", "").ToUpper();
        }

        //public static int ExportToSchDat(ProObAttr ObAttr)
        //{
        //    int rs = 0;
        //    string errinfo = string.Empty;
        //    SaveFileDialog savedialog = new SaveFileDialog();
        //    savedialog.FileName = ObAttr.ProName + "(" + ObAttr.CAD + ")";
        //    savedialog.Filter = "Data Files(*.dat)|*.dat";
        //    if (savedialog.ShowDialog() == DialogResult.OK)
        //    {
        //        string filepath = savedialog.FileName;
        //        if (filepath.Substring(filepath.Length - 4, 4).ToLower() != ".dat")
        //            filepath = filepath + ".dat";
        //        try
        //        {
        //            Application.DoEvents();

        //            #region 导出参数


        //            List<ProObAttr> oblist = new List<ProObAttr>();
        //            oblist.Add(ObAttr);

        //            DataSet dsProObAttr = ProObAttr.ProObAttrToDataSet(oblist);

        //            rs = RWOutFiles.DataSetToXMl(dsProObAttr, filepath, ref errinfo) ? 0 : -1;

        //            #endregion

        //            GC.Collect();
        //        }
        //        catch (Exception ex)
        //        {
        //            MessageBox.Show("导出失败,错误原因:") + ex.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //            return -1;
        //        }
        //        if (rs == 0)
        //            MessageBox.Show("导出成功"), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        //        else
        //            MessageBox.Show("导出失败,错误原因:") + errinfo, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);

        //    }
        //    return rs;
        //}

        //public static List<ProObAttr> ImportFromSchDat()
        //{

        //    OpenFileDialog opendialog = new OpenFileDialog();
        //    List<ProObAttr> oblist = new List<ProObAttr>();
        //    opendialog.Filter = "Data Files(*.dat)|*.dat";
        //    if (opendialog.ShowDialog() == DialogResult.OK)
        //    {
        //        string filepath = opendialog.FileName;

        //        try
        //        {
        //            Application.DoEvents();
        //            string Xmlstr = File.ReadAllText(filepath);

        //            #region 导入参数

        //            string errinfo = string.Empty;

        //            oblist = ProObAttr.StrToProObAttr(Xmlstr, ref errinfo);

        //            #endregion

        //            GC.Collect();
        //        }
        //        catch (Exception ex)
        //        {
        //            MessageBox.Show("导入失败,错误原因:") + ex.ToString(), "提示"), MessageBoxButtons.OK, MessageBoxIcon.Error);
        //            return null;
        //        }
        //    }
        //    return oblist;
        //}
        
    }

       
}
